package com.demo.mongodb;

import com.mongodb.Block;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.*;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.bson.Document;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Indexes.descending;

public class App {

    public static void main(String[] args) {
        MongoClient mongoClient = new MongoClient("localhost", 27017);
        System.out.println("正在连接数据库...");
        MongoDatabase database = mongoClient.getDatabase("mydb");
        System.out.println("数据库连接成功...");
        MongoCollection<Document> collection = database.getCollection("test");
//        insetDocument(collection);
//        insetDocuments(collection);
//        findFirst(collection);
        findAll(collection);
//        findByFilter(collection);
//        querySet(collection);
//        updateMany(collection);
//        findBySort(collection);
//        updateOne(collection);
//        deleteMany(collection);
//        orderedBulk(collection);
        mongoClient.close();
    }

    /**
     * insert one document
     * @param collection
     */
    public static void insetDocument(MongoCollection<Document> collection) {
        Document document = new Document("name", "MongoDB")
                .append("type", "database")
                .append("count", 1)
                .append("info", new Document("x", 203).append("y", 102));
        collection.insertOne(document);
        System.out.println("文档插入成功");
    }

    /**
     * insert many document
     * @param collection
     */
    public static void insetDocuments(MongoCollection<Document> collection) {
        List<Document> documents = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            documents.add(new Document("i", i));
        }
        collection.insertMany(documents);
        System.out.println("文档批量插入成功");
    }

    public static void findFirst(MongoCollection<Document> collection) {
        Document myDoc = collection.find().first();
        System.out.println(myDoc.toJson());
    }

    public static void findAll(MongoCollection<Document> collection) {
        MongoCursor<Document> cursor = collection.find().iterator();
        try {
            while (cursor.hasNext()) {
                System.out.println(cursor.next().toJson());
            }
        } finally {
            cursor.close();
        }
    }

    public static void findByFilter(MongoCollection<Document> collection) {
        Document myDoc = collection.find(eq("i", 71)).first();
        System.out.println(myDoc.toJson());
    }

    public static void querySet(MongoCollection<Document> collection) {
        Block<Document> printBlock = document -> System.out.println(document);
        collection.find(gt("i", 50)).forEach(printBlock);
    }

    public static void findBySort(MongoCollection<Document> collection) {
        Document myDoc = collection.find(exists("i")).sort(descending("i")).first();
        System.out.println(myDoc.toJson());
    }

    public static void updateOne(MongoCollection<Document> collection) {
        collection.updateOne(eq("i", 10), new Document("$set", new Document("i", 110)));
    }

    public static void updateMany(MongoCollection<Document> collection) {
        UpdateResult updateResult = collection.updateMany(lt("i", 100), new Document("$inc", new Document("i", 100)));
        System.out.println(updateResult.getModifiedCount());
    }

    public static void deleteOne(MongoCollection<Document> collection) {
        collection.deleteOne(eq("i", 110));
    }

    public static void deleteMany(MongoCollection<Document> collection) {
        DeleteResult deleteResult = collection.deleteMany(gte("i", 100));
        System.out.println(deleteResult.getDeletedCount());
    }

    public static void orderedBulk(MongoCollection<Document> collection) {
        collection.bulkWrite(
                Arrays.asList(new InsertOneModel<>(new Document("_id", 4)),
                        new InsertOneModel<>(new Document("_id", 5)),
                        new InsertOneModel<>(new Document("_id", 6)),
                        new UpdateOneModel<>(new Document("_id", 1),
                                new Document("$set", new Document("x", 2))),
                        new DeleteOneModel<>(new Document("_id", 2)),
                        new ReplaceOneModel<>(new Document("_id", 3),
                                new Document("_id", 3).append("x", 4))));
    }

    public static void unOrderedBulk(MongoCollection<Document> collection) {
        collection.bulkWrite(
                Arrays.asList(new InsertOneModel<>(new Document("_id", 4)),
                        new InsertOneModel<>(new Document("_id", 5)),
                        new InsertOneModel<>(new Document("_id", 6)),
                        new UpdateOneModel<>(new Document("_id", 1),
                                new Document("$set", new Document("x", 2))),
                        new DeleteOneModel<>(new Document("_id", 2)),
                        new ReplaceOneModel<>(new Document("_id", 3),
                                new Document("_id", 3).append("x", 4))),
                new BulkWriteOptions().ordered(false));
    }
}
